﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;


namespace SpeciesDatabaseInterface
{
    class SpeciesLogic
    {
        public static void InsertAnimal(string name, int lifeSpan, string color, string size, string breed) 
        {
            SpeciesEntities entities = new SpeciesEntities();
            Species newSpecies = new Species();
            newSpecies.Name = name;
            newSpecies.AverageLifeSpan = lifeSpan;
            newSpecies.Color = color;
            newSpecies.Size = size;
            entities.Species.AddObject(newSpecies);
            entities.SaveChanges();
            Species specie = entities.Species.FirstOrDefault(p => p.SpecieID == newSpecies.SpecieID);
            Animal animal = new Animal();
            animal.AnimalID = newSpecies.SpecieID;
            animal.Breed = breed;
            specie.Animal = animal;
            entities.SaveChanges();
        }

        public static void DeleteAnimal(int id)
        {
            SpeciesEntities entities = new SpeciesEntities();
            Species specie = entities.Species.FirstOrDefault(s => s.SpecieID == id);
            if (specie == null || specie.Animal == null) 
            {
                throw new ArgumentOutOfRangeException("No such animal");
            }
            entities.Species.DeleteObject(specie);
            entities.SaveChanges();
        }

        public static void DeletePlant(int id)
        {
            SpeciesEntities entities = new SpeciesEntities();
            Species specie = entities.Species.FirstOrDefault(s => s.SpecieID == id);
            if (specie == null || specie.Plant == null)
            {
                throw new ArgumentOutOfRangeException("No such plant");
            }
            entities.Species.DeleteObject(specie);
            entities.SaveChanges();
        }

        public static void DeleteMushroom(int id)
        {
            SpeciesEntities entities = new SpeciesEntities();
            Species specie = entities.Species.FirstOrDefault(s => s.SpecieID == id);
            if (specie == null || specie.Mushroom == null)
            {
                throw new ArgumentOutOfRangeException("No such mushroom");
            }
            entities.Species.DeleteObject(specie);
            entities.SaveChanges();
        }

        public static void InsertPlant(string name, int lifeSpan, string color, string size, int hight)
        {
            SpeciesEntities entities = new SpeciesEntities();
            Species newSpecies = new Species();
            newSpecies.Name = name;
            newSpecies.AverageLifeSpan = lifeSpan;
            newSpecies.Color = color;
            newSpecies.Size = size;
            entities.Species.AddObject(newSpecies);
            entities.SaveChanges();
            Species specie = entities.Species.FirstOrDefault(p => p.SpecieID == newSpecies.SpecieID);
            Plant plant = new Plant();
            plant.PlantID= newSpecies.SpecieID;
            plant.MaximumHight = hight;
            specie.Plant = plant;
            entities.SaveChanges();
        }

        public static void InsertMashroom(string name, int lifeSpan, string color, string size, bool isPoisonous)
        {
            SpeciesEntities entities = new SpeciesEntities();
            Species newSpecies = new Species();
            newSpecies.Name = name;
            newSpecies.AverageLifeSpan = lifeSpan;
            newSpecies.Color = color;
            newSpecies.Size = size;
            entities.Species.AddObject(newSpecies);
            entities.SaveChanges();
            Species specie = entities.Species.FirstOrDefault(p => p.SpecieID == newSpecies.SpecieID);
            Mushroom mush = new Mushroom();
            mush.MushroomID = newSpecies.SpecieID;
            mush.IsPoisonous = isPoisonous;
            specie.Mushroom = mush;
            entities.SaveChanges();
        }

        public static void InsertCountry(string continent, string country) 
        {
            SpeciesEntities entities = new SpeciesEntities();
            Continent perantContinent = entities.Continents.FirstOrDefault(c => c.Name == continent);
            if (perantContinent == null) 
            {
                perantContinent = new Continent();
                perantContinent.Name = continent;
                entities.Continents.AddObject(perantContinent);
            }
            Country newCountry = new Country();
            newCountry.Name = country;
            perantContinent.Countries.Add(newCountry);
            entities.SaveChanges();
        }

        public static void DeleteCountry(int id)
        {
            SpeciesEntities entities = new SpeciesEntities();
            Country country = entities.Countries.FirstOrDefault(s => s.CountryID == id);
            if (country ==null)
            {
                throw new ArgumentOutOfRangeException("No such country");
            }
            entities.Countries.DeleteObject(country);
            entities.SaveChanges();
        }

        public static void UpdateCountry(int id, string name, int continentId)
        {
            SpeciesEntities entities = new SpeciesEntities();
            Country country = entities.Countries.FirstOrDefault(c => c.CountryID == id);
            Continent continent = entities.Continents.FirstOrDefault(c => c.ContinentID == continentId);
            if (country == null || continent ==null)
            {
                throw new ArgumentOutOfRangeException("Invalid Country or Continent ID");
            }
            country.ContinentID = continentId;
            country.Name = name;
            entities.SaveChanges();
        }

        public static void AddContinent(string name) 
        {
            SpeciesEntities entities = new SpeciesEntities();
            if (entities.Continents.FirstOrDefault(e => e.Name == name) == null) 
            {
                throw new ArgumentOutOfRangeException("already exists");
            }
            Continent continent = new Continent();
            continent.Name = name;
            entities.Continents.AddObject(continent);
            entities.SaveChanges();
        }

        public static void DeleteContinent(int id)
        {
            SpeciesEntities entities = new SpeciesEntities();
            Continent continent = entities.Continents.FirstOrDefault(c => c.ContinentID == id);
            if (continent == null)
            {
                throw new ArgumentOutOfRangeException("Continent does not exist");
            }

            entities.Continents.DeleteObject(continent);
            entities.SaveChanges();
        }

        public static void UpdateContinent(int id, string name) 
        {
            SpeciesEntities entities = new SpeciesEntities();
            Continent continent = entities.Continents.FirstOrDefault(c => c.ContinentID == id);
            if (continent == null)
            {
                throw new ArgumentOutOfRangeException("Continent does not exist");
            }

            continent.Name = name;
            entities.SaveChanges();

        }

        public static void DeletePoisonousMusshrooms(string continent) 
        {
            SpeciesEntities entities = new SpeciesEntities();
            using (TransactionScope scope = new TransactionScope())
            {
                int mushrooms = 0;
                int plants = 0;
                foreach (var Contry in entities.Continents.Include("Countries.Species.Mushroom").
                    Include("Countries.Species.Plant").FirstOrDefault(c => c.Name == continent).Countries)
                {
                    foreach (var specie in Contry.Species)
                    {

                        if (specie.Mushroom != null && specie.Mushroom.IsPoisonous == true)
                        {
                            entities.Species.DeleteObject(specie);
                            entities.SaveChanges();
                        }
                    }
                    mushrooms += Contry.Species.Count(s => s.Mushroom != null);
                    plants += Contry.Species.Count(s => s.Plant != null);
                }
                if (mushrooms >= plants) 
                {
                    scope.Complete();
                }

            }
        }

    }
}
